/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.ipti.br.tag.bean;

import org.ipti.br.tag.bo.ActorBO;
import org.ipti.br.tag.bo.AddInfoPersonageBO;
import org.ipti.br.tag.bo.AdditionalInfoBO;
import org.ipti.br.tag.bo.AdditionalInfoTypeBO;
import org.ipti.br.tag.bo.AddressBO;
import org.ipti.br.tag.bo.JuridicBO;
import org.ipti.br.tag.bo.NeighborhoodBO;
import org.ipti.br.tag.bo.PeriodBO;
import org.ipti.br.tag.bo.StreetBO;
import org.ipti.br.tag.bo.UnityBO;
import org.ipti.br.tag.bo.ZipcodeBO;
import org.ipti.br.tag.entity.Actor;
import org.ipti.br.tag.entity.AdditionalInfo;
import org.ipti.br.tag.entity.AdditionalInfoType;
import org.ipti.br.tag.entity.Address;
import org.ipti.br.tag.entity.Juridic;
import org.ipti.br.tag.entity.Neighborhood;
import org.ipti.br.tag.entity.Period;
import org.ipti.br.tag.entity.Street;
import org.ipti.br.tag.entity.Unity;
import org.ipti.br.tag.entity.Zipcode;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.inject.Inject;
import javax.faces.model.SelectItem;
import org.ipti.br.tag.bean.lazy.LazyActorDataModel;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import org.ipti.br.tag.bo.PerformanceBO;
import org.ipti.br.tag.entity.Performance;

/**
 *
 * @author root
 */
@Named("unityEdit")
@SessionScoped
public class UnityEditBean extends AppBaseBean {

    @Inject
    private ActorBO actorBO;
    @Inject
    private AddInfoPersonageBO addInfoPersonageBO;
    @Inject
    private AdditionalInfoBO additionalInfoBO;
    @Inject
    private AdditionalInfoTypeBO additionalInfoTypeBO;
    @Inject
    private AddressBO addressBO;
    @Inject
    private JuridicBO juridicBO;
    @Inject
    private PeriodBO periodBO;
    @Inject
    private ZipcodeBO zipcodeBO;
    @Inject
    private NeighborhoodBO neighborhoodBO;
    @Inject
    private StreetBO streetBO;
    @Inject
    private UnityBO unityBO;
    @Inject
    private SessionBean sessionBean;
    @Inject
    private PerformanceBO performanceBO;
    private Address address;
    private Juridic juridic;
    private Unity unity;
    private Zipcode zipcode;
    private int organizationType;
    private Long periodID;
    private Long postalCodeID;
    private Long unityFatherID;
    private Long unityID;
    private String neighborhood;
    private String organizationFather;
    private String street;
    private String cep;
    private boolean needJuridic;
    private boolean deactivatedIsNull;
    private boolean showAddress;
    private List<AdditionalInfo> additionalInfoList;
    private List<SelectItem> additionalInfoTypeList;
    private List<SelectItem> periodList;
    private List<SelectItem> unitiesFather;
    private Actor actor;
    private Date deactivation;
    private LazyActorDataModel actors;

    public UnityEditBean() {
    }

    public void preEdit() {
        if (actor.getDeactivated() != null) {
            deactivation = actor.getDeactivated().getTime();
        }
    }

    public List<AdditionalInfo> personAdditionalInfo(Long personID) {
        return additionalInfoBO.findAddInfosPerPerson(personID);
    }

    public void editActor() {
        try {
            Actor actorAux = actorBO.find(actor.getId());
            actorAux.setActivated(null);
            actorAux.setDeactivated(null);
            actorBO.edit(actorAux);

            if (deactivation == null) {
                actor.setDeactivated(null);
            } else {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(deactivation);
                actor.setDeactivated(calendar);
            }
            actorAux.setActivated(actor.getActivated());
            actorAux.setDeactivated(actor.getDeactivated());
            actorBO.edit(actorAux);
            actor = null;
            deactivation = null;
            //init();
            addInfoMessage("msg", "Operação realizada com sucesso", null);
        } catch (Exception ex) {
            addErrorMessage("msg", "Um erro foi encontrado", null);
        }
    }

    public void searchCEP() {
        neighborhood = "";
        street = "";
        zipcode = zipcodeBO.searchByCode(Integer.parseInt(cep));
        if (zipcode == null) {
            showAddress = false;
            addInfoMessage("unityEditView:addresEditForm:cep", "CEP não cadastrado.", null);
        } else {
            if (zipcode.getNeighborhood() != null) {
                neighborhood = zipcode.getNeighborhood().getName();
            }
            if (zipcode.getStreet() != null) {
                street = zipcode.getStreet().getName();
            }
            showAddress = true;
        }
    }

    public List<String> neighborhoodComplete(String query) {
        return neighborhoodBO.neighborhoodList(query, zipcode.getCity());
    }

    public List<String> streetComplete(String query) {
        return streetBO.streetList(query, zipcode.getCity());
    }

    public void initialize() {
        unity = getUnityBO().find(unityID);

        List<Long> unities = new ArrayList<Long>();
        unities.add(unityID);
        actors = new LazyActorDataModel(actorBO.getActorDAO(), unities, null);

        deactivatedIsNull = (unity.getDeactivated() == null);
        if (deactivatedIsNull) {
            unity.setDeactivated(Calendar.getInstance());
        }

        if (unity.getUnityFather() != null) {
            unityFatherID = unity.getUnityFather().getId();
            organizationFather = unity.getUnityFather().getOrganization().getName();
        }

        periodID = unity.getPeriod().getId();
        loadNeedJuridic();
        if (needJuridic) {
            juridic = juridicBO.find(unity.getPerson().getId());
            address = juridic.getAddress();


            zipcode = address.getZipcode();
            cep = String.valueOf(address.getZipcode().getCode());
            neighborhood = address.getNeighborhood().getName();
            street = address.getStreet().getName();

            String number = address.getNumber();
            String complement = address.getComplement();
            address = new Address();
            address.setNumber(number);
            address.setComplement(complement);
            showAddress = true;
        }
    }

    public boolean validateZipcode() {
        if (zipcode != null || !needJuridic) {
            return true;
        } else {
            addErrorMessage("msg", "'Endereço' é obrigatório", null);
            return false;
        }
    }

    public boolean validateDates() {
        if (deactivatedIsNull || unity.getActivated().getTime().before(unity.getDeactivated().getTime())) {
            return true;
        } else {
            addErrorMessage("msg", "'Desativação' deve ser após 'Ativação'", null);
            return false;
        }
    }

    public boolean validateBirthday() {
        if (needJuridic) {
            if (juridic.getBirthday().before(Calendar.getInstance())) {
                return true;
            } else {
                addErrorMessage("msg", "'Data de Fundação' deve ser anterior à data atual", null);
                return false;
            }
        } else {
            return true;
        }
    }

    public void edit() {
        if (validateDates() & validateBirthday() & validateZipcode()) {
            if (needJuridic) {

                Calendar birthday = juridic.getBirthday();
                juridic.setBirthday(null);
                getJuridicBO().edit(juridic);
                juridic.setBirthday(birthday);
                getJuridicBO().edit(juridic);

                for (AdditionalInfo ai : additionalInfoList) {
                    ai.setPerson(juridic);
                    getAdditionalInfoBO().edit(ai);
                }

                address.setZipcode(zipcode);
                Neighborhood neighborhoodAux = neighborhoodBO.searchByNameCity(neighborhood, zipcode.getCity().getId());
                Street streetAux = streetBO.searchByNameCity(street, zipcode.getCity().getId());

                if (neighborhoodAux == null) {
                    neighborhoodAux = new Neighborhood(neighborhood, zipcode.getCity());
                    neighborhoodBO.create(neighborhoodAux);
                }
                if (streetAux == null) {
                    streetAux = new Street(street, zipcode.getCity());
                    streetBO.create(streetAux);
                }

                address.setNeighborhood(neighborhoodAux);
                address.setStreet(streetAux);

                Long addressID = addressBO.searchExactAddress(address);

                if (addressID == null || addressID.equals(0L)) {
                    addressBO.create(address);
                } else {
                    address.setId(addressID);
                }

                juridic.setAddress(address);
                juridicBO.edit(juridic);
                unity.setPerson(juridic);
            }

            if (deactivatedIsNull) {
                unity.setDeactivated(null);
            }
            Calendar a = unity.getActivated();
            Calendar d = unity.getDeactivated();
            unity.setActivated(null);
            unity.setDeactivated(null);
            getUnityBO().edit(unity);
            unity.setActivated(a);
            unity.setDeactivated(d);

            Period period = new Period();
            period.setId(periodID);
            unity.setPeriod(period);

            getUnityBO().edit(unity);

            initialize();
            addInfoMessage("msg", "Edição realizada com sucesso.", null);
        }
    }

    public void loadNeedJuridic() {
        if (organizationType == 0) {
            needJuridic = false;
        } else {
            needJuridic = true;
        }
    }

    public void loadAddInfoList() {
        additionalInfoList = new ArrayList<AdditionalInfo>();
        if (needJuridic) {
            additionalInfoList = getAdditionalInfoBO().findAddInfosPerPerson(unity.getPerson().getId());
        }
    }

    public void loadAddInfoTypeList() {
        additionalInfoTypeList = new ArrayList<SelectItem>();
        additionalInfoTypeList.add(new SelectItem(0L, "Selecione um tipo"));
        for (AdditionalInfoType ait : getAdditionalInfoTypeBO().findAllOrder()) {
            additionalInfoTypeList.add(new SelectItem(ait.getId(), ait.getAcronym()));
        }
    }

    public void loadPeriodList() {
        periodList = new ArrayList<SelectItem>();
        for (Period p : getPeriodBO().findAllOrder()) {
            periodList.add(new SelectItem(p.getId(), p.getDescription()));
        }
    }

    public void loadUnitiesFather() {
        unitiesFather = new ArrayList<SelectItem>();
        for (Unity u : getUnityBO().unityChildrenPerOrganization(sessionBean.getLoggedActor().getUnity(),
                unity.getUnityFather().getOrganization())) {
            unitiesFather.add(new SelectItem(u.getId(), u.getName()));
        }

        if (unitiesFather.size() == 1) {
            unityFatherID = (Long) unitiesFather.get(0).getValue();
        }
    }

    public boolean checkUnity(Unity unityToFind, Unity userUnity) {
        boolean a = false;

        if (userUnity != null) {
            if (userUnity.getId() == unityToFind.getId()) {
                a = true;
            } else {
                for (Unity u : getUnityBO().getUnityChildren(userUnity.getId())) {
                    if (checkUnity(unityToFind, u)) {
                        a = true;
                        break;
                    }
                }
            }
        }

        return a;
    }

    public boolean dependecyCheck(Actor actorT) {
        if (actorT.getSimpleFrequencys().isEmpty()) {
            //List<Performance> p = performanceBO.findPerfomances(actorT);
            if(!performanceBO.hasPerfomances(actorT)){
                return true;
            }
        }
        return false;
    }

    public void deleteActor() {
        try {
            actorBO.removePerformances(actor);
            actorBO.remove(actor);
            addInfoMessage("msg", "Aluno excluído com sucesso", null);
        } catch (Exception e) {
            addErrorMessage("msg", "Não possível excluir o aluno.", null);
            e.printStackTrace();
        }
    }

    public AddInfoPersonageBO getAddInfoPersonageBO() {
        return addInfoPersonageBO;
    }

    public void setAddInfoPersonageBO(AddInfoPersonageBO addInfoPersonageBO) {
        this.addInfoPersonageBO = addInfoPersonageBO;
    }

    public AdditionalInfoBO getAdditionalInfoBO() {
        return additionalInfoBO;
    }

    public void setAdditionalInfoBO(AdditionalInfoBO additionalInfoBO) {
        this.additionalInfoBO = additionalInfoBO;
    }

    public AdditionalInfoTypeBO getAdditionalInfoTypeBO() {
        return additionalInfoTypeBO;
    }

    public void setAdditionalInfoTypeBO(AdditionalInfoTypeBO additionalInfoTypeBO) {
        this.additionalInfoTypeBO = additionalInfoTypeBO;
    }

    public AddressBO getAddressBO() {
        return addressBO;
    }

    public void setAddressBO(AddressBO addressBO) {
        this.addressBO = addressBO;
    }

    public JuridicBO getJuridicBO() {
        return juridicBO;
    }

    public void setJuridicBO(JuridicBO juridicBO) {
        this.juridicBO = juridicBO;
    }

    public PeriodBO getPeriodBO() {
        return periodBO;
    }

    public void setPeriodBO(PeriodBO periodBO) {
        this.periodBO = periodBO;
    }

    public UnityBO getUnityBO() {
        return unityBO;
    }

    public void setUnityBO(UnityBO unityBO) {
        this.unityBO = unityBO;
    }

    public SessionBean getSessionBean() {
        return sessionBean;
    }

    public void setSessionBean(SessionBean sessionBean) {
        this.sessionBean = sessionBean;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public Juridic getJuridic() {
        return juridic;
    }

    public void setJuridic(Juridic juridic) {
        this.juridic = juridic;
    }

    public Unity getUnity() {
        return unity;
    }

    public void setUnity(Unity unity) {
        this.unity = unity;
    }

    public int getOrganizationType() {
        return organizationType;
    }

    public void setOrganizationType(int organizationType) {
        this.organizationType = organizationType;
    }

    public Long getPeriodID() {
        return periodID;
    }

    public void setPeriodID(Long periodID) {
        this.periodID = periodID;
    }

    public Long getPostalCodeID() {
        return postalCodeID;
    }

    public void setPostalCodeID(Long postalCodeID) {
        this.postalCodeID = postalCodeID;
    }

    public Long getUnityFatherID() {
        return unityFatherID;
    }

    public void setUnityFatherID(Long unityFatherID) {
        this.unityFatherID = unityFatherID;
    }

    public Long getUnityID() {
        return unityID;
    }

    public void setUnityID(Long unityID) {
        this.unityID = unityID;
    }

    public String getNeighborhood() {
        return neighborhood;
    }

    public void setNeighborhood(String neighborhood) {
        this.neighborhood = neighborhood;
    }

    public String getOrganizationFather() {
        return organizationFather;
    }

    public void setOrganizationFather(String organizationFather) {
        this.organizationFather = organizationFather;
    }

    public boolean isNeedJuridic() {
        return needJuridic;
    }

    public void setNeedJuridic(boolean needJuridic) {
        this.needJuridic = needJuridic;
    }

    public List<AdditionalInfo> getAdditionalInfoList() {
        if (additionalInfoList == null) {
            loadAddInfoList();
        }
        return additionalInfoList;
    }

    public void setAdditionalInfoList(List<AdditionalInfo> additionalInfoList) {
        this.additionalInfoList = additionalInfoList;
    }

    public List<SelectItem> getAdditionalInfoTypeList() {
        if (additionalInfoTypeList == null) {
            loadAddInfoTypeList();
        }
        return additionalInfoTypeList;
    }

    public void setAdditionalInfoTypeList(List<SelectItem> additionalInfoTypeList) {
        this.additionalInfoTypeList = additionalInfoTypeList;
    }

    public List<SelectItem> getPeriodList() {
        if (periodList == null) {
            loadPeriodList();
        }
        return periodList;
    }

    public void setPeriodList(List<SelectItem> periodList) {
        this.periodList = periodList;
    }

    public List<SelectItem> getUnitiesFather() {
        if (unity.getUnityFather() != null && unitiesFather == null) {
            loadUnitiesFather();
        }
        return unitiesFather;
    }

    public void setUnitiesFather(List<SelectItem> unitiesFather) {
        this.unitiesFather = unitiesFather;
    }

    public boolean isDeactivatedIsNull() {
        return deactivatedIsNull;
    }

    public void setDeactivatedIsNull(boolean deactivatedIsNull) {
        this.deactivatedIsNull = deactivatedIsNull;
    }

    public String getCep() {
        return cep;
    }

    public void setCep(String cep) {
        this.cep = cep;
    }

    public boolean isShowAddress() {
        return showAddress;
    }

    public void setShowAddress(boolean showAddress) {
        this.showAddress = showAddress;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public Zipcode getZipcode() {
        return zipcode;
    }

    public void setZipcode(Zipcode zipcode) {
        this.zipcode = zipcode;
    }

    public LazyActorDataModel getActors() {
        return actors;
    }

    public void setActors(LazyActorDataModel actors) {
        this.actors = actors;
    }

    public Actor getActor() {
        return actor;
    }

    public void setActor(Actor actor) {
        this.actor = actor;
    }

    public Date getDeactivation() {
        return deactivation;
    }

    public void setDeactivation(Date deactivation) {
        this.deactivation = deactivation;
    }
}